package com.jqj;

import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.Instrumentation;
import java.security.ProtectionDomain;
import java.util.List;
import java.util.concurrent.TimeUnit;

import com.sun.tools.attach.VirtualMachine;
import com.sun.tools.attach.VirtualMachineDescriptor;

/*
 * @Desc: Java Agent 测试
 * @Author: lijingzheng
 * @Date: 2024/12/9
 */
public class JavaAgentTest {

    public static void main(String[] args) throws Exception {
        //获取当前系统中所有 运行中的 虚拟机
        System.out.println("running JVM start ");
        List<VirtualMachineDescriptor> list = VirtualMachine.list();
        for (VirtualMachineDescriptor vmd : list) {
            //如果虚拟机的名称为 xxx 则 该虚拟机为目标虚拟机，获取该虚拟机的 pid
            //然后加载 agent.jar 发送给该虚拟机
            System.out.println(vmd.displayName());
            if (vmd.displayName().endsWith("com.tongmmp.TongMMPApplication")) {
                System.out.println(vmd.id());
                VirtualMachine virtualMachine = VirtualMachine.attach(vmd.id());
                virtualMachine.loadAgent("C:\\Users\\EDY\\IdeaProjects\\MyJavaAgentByMaven\\target\\MyJavaAgentByMaven-1.0-SNAPSHOT.jar");
                System.out.println("attach");

                TimeUnit.SECONDS.sleep(30);
                virtualMachine.detach();
                System.out.println("detach");
            }
        }
    }

    public static void agentmain(String agentArgs, Instrumentation instrumentation) throws Exception  {
        System.out.println("Adding a AopAgentTest instance to the JVM.");
        instrumentation.addTransformer(new AopAgentTransformer());
    }

    /**
     * 该方法在main方法之前运行，与main方法运行在同一个JVM中
     */
    public static void premain(String arg, Instrumentation instrumentation) {
        System.out.println("agent的premain(String arg, Instrumentation instrumentation)方法");
//        instrumentation.addTransformer(new MyTransformer());

        System.out.println("Adding a AopAgentTest instance to the JVM.");
        instrumentation.addTransformer(new AopAgentTransformer());
    }

    static class MyTransformer implements ClassFileTransformer {
        @Override
        public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
                                ProtectionDomain protectionDomain, byte[] classfileBuffer) {
            // 打印正在加载的类的名称（不包括包名前的"/")
            System.out.println("Loading class: " + className.replace("/", "."));
            // 这里我们不修改字节码，所以直接返回原字节码
            return classfileBuffer;
        }
    }

    /**
     * 若不存在 premain(String agentArgs, Instrumentation inst)，
     * 则会执行 premain(String agentArgs)
     */
    public static void premain(String arg) {
        System.out.println("agent的premain(String arg)方法");
    }


}